#!/usr/bin/env python3
"""
地理勘查记录系统 API 集成测试脚本
"""

import requests
import json
import time
import os
from datetime import datetime, timedelta

class GeoSurveyAPITester:
    def __init__(self, base_url='http://127.0.0.1:8000'):
        self.base_url = base_url
        self.access_token = None
        self.user_id = None
        self.survey_id = None
        
    def print_result(self, test_name, success, details=None):
        """打印测试结果"""
        status = "✅ PASS" if success else "❌ FAIL"
        print(f"{status} {test_name}")
        if details:
            print(f"   Details: {details}")
    
    def register_user(self):
        """测试用户注册"""
        url = f"{self.base_url}/api/users/register/"
        data = {
            "username": f"testuser_{int(time.time())}",
            "email": f"test_{int(time.time())}@example.com",
            "phone": "13888888888",
            "password": "testpass123",
            "password_confirm": "testpass123"
        }
        
        try:
            response = requests.post(url, json=data)
            success = response.status_code == 201
            if success:
                result = response.json()
                self.access_token = result.get('access_token')
                self.user_id = result.get('user', {}).get('id')
            
            self.print_result("用户注册", success, 
                            f"Status: {response.status_code}, Token: {bool(self.access_token)}")
            return success
        except Exception as e:
            self.print_result("用户注册", False, str(e))
            return False
    
    def login_user(self):
        """测试用户登录"""
        url = f"{self.base_url}/api/auth/token/"
        data = {
            "username": "testuser",
            "password": "testpass123"
        }
        
        try:
            response = requests.post(url, json=data)
            success = response.status_code == 200
            if success:
                result = response.json()
                self.access_token = result.get('access')
            
            self.print_result("用户登录", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("用户登录", False, str(e))
            return False
    
    def get_headers(self):
        """获取请求头"""
        return {
            'Authorization': f'Bearer {self.access_token}',
            'Content-Type': 'application/json'
        }
    
    def create_survey_record(self):
        """测试创建勘查记录"""
        url = f"{self.base_url}/api/surveys/"
        data = {
            "location_name": "集成测试地点",
            "address": "北京市朝阳区测试街道123号",
            "latitude": "39.908823",
            "longitude": "116.397470",
            "orientation": "坐北朝南",
            "notes": "这是一条集成测试记录",
            "survey_date": datetime.now().isoformat()
        }
        
        try:
            response = requests.post(url, json=data, headers=self.get_headers())
            success = response.status_code == 201
            if success:
                result = response.json()
                self.survey_id = result.get('id')
            
            self.print_result("创建勘查记录", success, 
                            f"Status: {response.status_code}, ID: {self.survey_id}")
            return success
        except Exception as e:
            self.print_result("创建勘查记录", False, str(e))
            return False
    
    def list_survey_records(self):
        """测试获取勘查记录列表"""
        url = f"{self.base_url}/api/surveys/"
        
        try:
            response = requests.get(url, headers=self.get_headers())
            success = response.status_code == 200
            if success:
                result = response.json()
                count = result.get('count', 0)
                details = f"Status: {response.status_code}, Count: {count}"
            else:
                details = f"Status: {response.status_code}"
            
            self.print_result("获取勘查记录列表", success, details)
            return success
        except Exception as e:
            self.print_result("获取勘查记录列表", False, str(e))
            return False
    
    def get_survey_detail(self):
        """测试获取勘查记录详情"""
        if not self.survey_id:
            self.print_result("获取勘查记录详情", False, "No survey ID available")
            return False
        
        url = f"{self.base_url}/api/surveys/{self.survey_id}/"
        
        try:
            response = requests.get(url, headers=self.get_headers())
            success = response.status_code == 200
            
            self.print_result("获取勘查记录详情", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("获取勘查记录详情", False, str(e))
            return False
    
    def update_survey_record(self):
        """测试更新勘查记录"""
        if not self.survey_id:
            self.print_result("更新勘查记录", False, "No survey ID available")
            return False
        
        url = f"{self.base_url}/api/surveys/{self.survey_id}/"
        data = {
            "location_name": "更新后的地点名称",
            "notes": "更新后的备注信息"
        }
        
        try:
            response = requests.patch(url, json=data, headers=self.get_headers())
            success = response.status_code == 200
            
            self.print_result("更新勘查记录", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("更新勘查记录", False, str(e))
            return False
    
    def search_survey_records(self):
        """测试搜索勘查记录"""
        url = f"{self.base_url}/api/surveys/search/"
        params = {
            "search": "测试",
            "start_date": (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d'),
            "end_date": (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d')
        }
        
        try:
            response = requests.get(url, params=params, headers=self.get_headers())
            success = response.status_code == 200
            if success:
                result = response.json()
                count = len(result) if isinstance(result, list) else 0
                details = f"Status: {response.status_code}, Results: {count}"
            else:
                details = f"Status: {response.status_code}"
            
            self.print_result("搜索勘查记录", success, details)
            return success
        except Exception as e:
            self.print_result("搜索勘查记录", False, str(e))
            return False
    
    def get_statistics(self):
        """测试获取统计数据"""
        endpoints = [
            "/api/surveys/statistics/",
            "/api/surveys/weekly_stats/",
            "/api/surveys/monthly_stats/",
            "/api/surveys/dashboard_stats/"
        ]
        
        success_count = 0
        for endpoint in endpoints:
            url = f"{self.base_url}{endpoint}"
            try:
                response = requests.get(url, headers=self.get_headers())
                success = response.status_code == 200
                if success:
                    success_count += 1
                
                self.print_result(f"统计数据 - {endpoint.split('/')[-2]}", success, 
                                f"Status: {response.status_code}")
            except Exception as e:
                self.print_result(f"统计数据 - {endpoint.split('/')[-2]}", False, str(e))
        
        return success_count == len(endpoints)
    
    def create_favorite_location(self):
        """测试创建常用地点"""
        url = f"{self.base_url}/api/favorites/"
        data = {
            "name": "集成测试常用地点",
            "address": "上海市浦东新区测试路456号",
            "latitude": "31.230416",
            "longitude": "121.473701"
        }
        
        try:
            response = requests.post(url, json=data, headers=self.get_headers())
            success = response.status_code == 201
            
            self.print_result("创建常用地点", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("创建常用地点", False, str(e))
            return False
    
    def test_unauthorized_access(self):
        """测试未授权访问"""
        url = f"{self.base_url}/api/surveys/"
        
        try:
            response = requests.get(url)  # 不带认证头
            success = response.status_code == 401
            
            self.print_result("未授权访问保护", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("未授权访问保护", False, str(e))
            return False
    
    def test_rate_limiting(self):
        """测试API限流"""
        url = f"{self.base_url}/api/surveys/"
        
        # 快速发送多个请求
        rate_limited = False
        for i in range(10):
            try:
                response = requests.get(url, headers=self.get_headers())
                if response.status_code == 429:
                    rate_limited = True
                    break
            except:
                pass
        
        # 这里不一定会触发限流，因为测试环境限流设置可能比较宽松
        self.print_result("API限流测试", True, 
                        f"Rate limited: {rate_limited} (may not trigger in test env)")
        return True
    
    def test_api_documentation(self):
        """测试API文档访问"""
        urls = [
            f"{self.base_url}/swagger/",
            f"{self.base_url}/redoc/"
        ]
        
        success_count = 0
        for url in urls:
            try:
                response = requests.get(url)
                success = response.status_code == 200
                if success:
                    success_count += 1
                
                doc_type = url.split('/')[-2]
                self.print_result(f"API文档 - {doc_type}", success, 
                                f"Status: {response.status_code}")
            except Exception as e:
                doc_type = url.split('/')[-2]
                self.print_result(f"API文档 - {doc_type}", False, str(e))
        
        return success_count > 0
    
    def delete_survey_record(self):
        """测试删除勘查记录"""
        if not self.survey_id:
            self.print_result("删除勘查记录", False, "No survey ID available")
            return False
        
        url = f"{self.base_url}/api/surveys/{self.survey_id}/"
        
        try:
            response = requests.delete(url, headers=self.get_headers())
            success = response.status_code == 204
            
            self.print_result("删除勘查记录", success, f"Status: {response.status_code}")
            return success
        except Exception as e:
            self.print_result("删除勘查记录", False, str(e))
            return False
    
    def run_all_tests(self):
        """运行所有集成测试"""
        print("🚀 开始运行地理勘查记录系统 API 集成测试")
        print("=" * 60)
        
        # 测试序列
        tests = [
            ("API文档访问", self.test_api_documentation),
            ("未授权访问保护", self.test_unauthorized_access),
            ("用户注册", self.register_user),
            ("创建勘查记录", self.create_survey_record),
            ("获取勘查记录列表", self.list_survey_records),
            ("获取勘查记录详情", self.get_survey_detail),
            ("更新勘查记录", self.update_survey_record),
            ("搜索勘查记录", self.search_survey_records),
            ("获取统计数据", self.get_statistics),
            ("创建常用地点", self.create_favorite_location),
            ("API限流测试", self.test_rate_limiting),
            ("删除勘查记录", self.delete_survey_record)
        ]
        
        passed = 0
        total = len(tests)
        
        for test_name, test_func in tests:
            print(f"\n📋 运行测试: {test_name}")
            try:
                if test_func():
                    passed += 1
                time.sleep(0.1)  # 避免请求过快
            except Exception as e:
                self.print_result(test_name, False, f"Exception: {str(e)}")
        
        print("\n" + "=" * 60)
        print(f"📊 测试总结: {passed}/{total} 通过")
        
        if passed == total:
            print("🎉 所有集成测试通过！")
        else:
            print(f"⚠️  {total - passed} 个测试失败")
        
        return passed == total


def main():
    """主函数"""
    import sys
    
    # 检查命令行参数
    base_url = sys.argv[1] if len(sys.argv) > 1 else 'http://127.0.0.1:8000'
    
    print(f"🔧 目标服务器: {base_url}")
    
    # 运行测试
    tester = GeoSurveyAPITester(base_url)
    success = tester.run_all_tests()
    
    # 退出码
    sys.exit(0 if success else 1)


if __name__ == '__main__':
    main()